package com.example.schooljava.exception;

import com.example.schooljava.util.Result;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;

/**
 * 功能描述
 *
 * @author: LDH
 * @date: 2022年08月24日 15:00
 */
@Aspect //配置切面
@Component
@Slf4j
public class ControllerAop {

    /**
     * 第一个 * 代表所有的方法
     * 第二个 * 前面com.example.schooljava.controller下面的所有类 然后后面* 代表方法
     * 最后面括号里面的 .. 代表所有参数
     *
     * 定义切入点，切入点为controller下的所有函数
     */
    @Pointcut("execution(* com.example.schooljava.controller.*.*(..))")
    public void webLog() {
    }


    @Async("new_Thread")
    public synchronized void pringLog(JoinPoint joinPoint, HttpServletRequest request, Object ret){

        // 获取当前时间
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date date = new Date();

        // 记录下请求内容
        log.info("请求时间 : " + formatter.format(date));
        log.info("请求地址 : " + request.getRequestURL().toString());
        log.info("请求方法 : " + request.getMethod());
        log.info("IP来源 : " + request.getRemoteAddr());
        log.info("请求方法 : " + joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName());
        if (!request.getRequestURL().toString().equals("http://localhost:9090/school/teacher/upload"))
            log.info("请求参数 : " + Arrays.toString(joinPoint.getArgs()));

        // 处理完请求，返回内容(获取的是前面方法返回的结果)
        log.info("返回结果 : " + ret);

    }

    /**
     *  前置通知：在连接点之前执行的通知
     *
     *  注意：这里用到了JoinPoint和RequestContextHolder。
     * 1）、通过JoinPoint可以获得通知的签名信息，如目标方法名、目标方法参数信息等；
     * 2）、通过RequestContextHolder来获取请求信息，Session信息；
     */
    @Before("webLog()")
    public void before(JoinPoint joinPoint) {
        // 接收到请求，记录请求内容
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();


    }

    @After("webLog()")
    public void after() {

    }

    @AfterThrowing(throwing = "ex", pointcut = "webLog()")
    public void beferException(Throwable ex) {

    }

    @AfterReturning(returning = "ret",pointcut = "webLog()")
    public void afterEnd(JoinPoint joinPoint, Object ret) throws Throwable {
        // 接收到请求，记录请求内容
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();

        pringLog(joinPoint,request,ret);

    }

}